use proc_macro2::TokenStream;
use quote::{format_ident, quote};



#[derive(Debug)]
pub struct AdcConfig {
    pub name: String,
    pub chs: Vec<u8>,
}

pub fn parse(attr: &str) -> AdcConfig {
    let attrs: Vec<&str> = attr.split("_").collect();
    let name = attrs[0].to_string();
    let mut chs = Vec::new();
    let infos = &attrs[1..];
    if infos.is_empty() {
        panic!("no chan");
    }
    for info in infos {
        let c = &info[2..];
        let c: u8 = c.parse().unwrap();
        chs.push(c);
    }
    AdcConfig { name, chs }
}

impl AdcConfig {

    pub fn config_smpr(&self) -> TokenStream {
        let mut expand = quote! {};
        let adc = format_ident!("{}", self.name);
        let mut smpr1_scs = Vec::new();
        let mut smpr2_scs = Vec::new();

        for ch in self.chs.iter() {
            let ch = *ch;
            let smp = format_ident!("smp{}", ch);
            let smp = quote! {
                .#smp().cycles239_5()
            };
            if ch < 10 {
                smpr2_scs.push(smp);
            } else {
                smpr1_scs.push(smp);
            }
        }
        if !smpr1_scs.is_empty() {
            let sc = quote! {
                #adc.smpr1.write(|w| {
                    w #(#smpr1_scs)*
                });
            };
            expand.extend(sc);
        }
        if !smpr2_scs.is_empty() {
            let sc = quote! {
                #adc.smpr2.write(|w| {
                    w #(#smpr2_scs)*
                });
            };
            expand.extend(sc);
        }

        expand
    }

    pub fn create_config_chan(&self) -> TokenStream {
        let mut expand = quote! {};
        let adc = format_ident!("{}", self.name);
        let mut sqr3_scs = Vec::new();
        let mut sqr2_scs = Vec::new();
        let mut sqr1_scs = Vec::new();
        let count = self.chs.len() as u8 - 1;
        let l = quote! {
            .l().variant(#count)
        };
        sqr1_scs.push(l);
        for (index, ch) in self.chs.iter().enumerate() {
            let sq = format_ident!("sq{}", index + 1);
            let sc = quote! {
                .#sq().variant(#ch)
            };
            if index < 6 {
                sqr3_scs.push(sc);
            } else if index < 12 {
                sqr2_scs.push(sc);
            } else if index < 16 {
                sqr1_scs.push(sc);
            } else {
                panic!("invalid ch")
            }
        }
        let sqr3 = quote! {
            #adc.sqr3.write(|w| {
                w #(#sqr3_scs)*
            });
        };
        expand.extend(sqr3);
        if !sqr2_scs.is_empty() {
            let sqr2 = quote! {
                #adc.sqr2.write(|w| {
                    w #(#sqr2_scs)*
                });
            };
            expand.extend(sqr2);
        }
        if !sqr1_scs.is_empty() {
            let sqr1 = quote! {
                #adc.sqr1.write(|w| {
                    w #(#sqr1_scs)*
                });
            };
            expand.extend(sqr1);
        }

        expand
    }
}
